﻿using Mapster.Utils;
using System.Linq.Expressions;

namespace WenAntdUI.Helps;

public static class ControlHelp
{
    /// <summary>
    /// 鼠标悬停选中
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="t"></param>
    /// <returns></returns>
    public static T MouseSelect<T>(this T t) where T : Control
    {
        t.MouseLeave += (s, e) =>
        {
            t.BackColor = Color.White;
            t.ForeColor = Color.Black;
        };
        t.MouseEnter += (s, e) =>
        {
            t.BackColor = Color.FromArgb(240, 240, 240);
            t.ForeColor = Color.FromArgb(0, 0, 0);
        };
        return t;
    }

    /// <summary>
    /// 触发属性改变
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="t"></param>
    /// <returns></returns>
    public static T OnPropertyChanged<T>(this T t) where T : Control
    {
        foreach (Binding binding in t.DataBindings)
        {
            binding.WriteValue();
        }
        return t;
    }
    /// <summary>
    /// 触发属性改变
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="t"></param>
    /// <param name="propertyName"></param>
    /// <returns></returns>
    public static T OnPropertyChanged<T>(this T t, string propertyName) where T : Control
    {
        foreach (Binding binding in t.DataBindings)
        {
            if (binding.PropertyName == propertyName)
                binding.WriteValue();
        }
        return t;
    }

    /// <summary>
    /// 触发属性改变
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="t"></param>
    /// <param name="expression"></param>
    /// <returns></returns>
    public static T OnPropertyChanged<T>(this T t, Expression<Func<T, object>> expression) where T : Control
    {
        var name = expression.GetMemberName();
        OnPropertyChanged(t, name);
        return t;
    }

    /// <summary>
    /// 设置属性值并触发属性改变
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="t"></param>
    /// <param name="expression"></param>
    /// <param name="value"></param>
    /// <returns></returns>
    /// <exception cref="ArgumentException"></exception>
    public static T SetPropertyChanged<T>(this T t, Expression<Func<T, object>> expression, object value) where T : Control
    {
        var name = expression.GetMemberName();

        var property = t.GetType().GetProperty(name);
        if (property != null)
        {
            property.SetValue(t, value);
            OnPropertyChanged(t, name);
        }
        else
        {
            throw new ArgumentException($"属性 {name} 不存在于类型 {t.GetType().Name} 中。");
        }
        return t;
    }
}
